#ifndef __GAME_MAP_H__
#define __GAME_MAP_H__

#include "bmp.h"
#include "lcd.h"

enum
{
    GRID_SIZE = 20,
    MAP_START_X = 200,
    MAP_START_Y = 0,
    MAP_WIDTH = 600,
    MAP_HEIGHT = 480,
    GRID_ROWS = MAP_HEIGHT / GRID_SIZE, // 行
    GRID_COLS = MAP_WIDTH / GRID_SIZE   // 列
};

enum GridState
{
    // 基础状态
    GRID_EMPTY = 0,     // 空格子
    GRID_SNAKE_BODY,    // 蛇身占据的格子
    GRID_AI_SNAKE_BODY, // AI蛇身占据的格子

    // 基础增长类果实
    GRID_FOOD_SCORE_1, // 加1分果实
    GRID_FOOD_SCORE_2, // 加2分果实

    // 功能效果类果实
    GRID_FOOD_SPEED_UP,   // 加速果实
    GRID_FOOD_SPEED_DOWN, // 减速果实
    GRID_FOOD_CONFUSE,    // 迷惑果实（方向反转）
    GRID_FOOD_AI_SNAKE,   // AI蛇果实（AI蛇出现）

    // 风险趣味类果实
    GRID_FOOD_BOMB // 炸弹果实（缩短蛇身/游戏结束）
};

class GameMap
{
protected:
    GameMap(int *mp, const char *bg_path) : mp(mp), bg(bg_path),
                                            fast_bg("./res/fast_bg.bmp"),
                                            slow_bg("./res/slow_bg.bmp"),
                                            food_score1("./res/food_score1.bmp"),
                                            food_score2("./res/food_score2.bmp"),
                                            food_speedup("./res/food_speed_up.bmp"),
                                            food_speeddown("./res/food_speed_down.bmp"),
                                            food_confuse("./res/food_confuse.bmp"),
                                            food_bomb("./res/food_bomb.bmp"),
                                            food_ai_snake("./res/food_ai_snake.bmp")
    {
        init();
    }

    virtual ~GameMap();

public:
    virtual int getScore1Prob() const = 0;
    virtual int getScore2Prob() const = 0;
    virtual int getSpeedUpProb() const = 0;
    virtual int getSpeedDownProb() const = 0;
    virtual int getConfuseProb() const = 0;
    virtual int getBombProb() const = 0;
    virtual int getAISnake() const = 0;
    virtual bool isCreatedAISnake() const = 0;
    virtual int getInitSpeed() const = 0;
    virtual int getMaxSpeed() const = 0;
    virtual int getMinSpeed() const = 0;
    virtual void setMaxFoodCount() = 0;

    BMP &getMap() { return bg; }
    GridState (&getGrid()) [GRID_ROWS][GRID_COLS]
    {
        return grid;
    } int &getFoodCount()
    {
        return food_count;
    }

    void init();
    void drawFood(int row, int col, GridState type);
    void generateRandomFood();
    void drawMap();

    // 创建和删除实例
    static GameMap *instance(int *mp, int difficulty = 0);
    static void delInstance();

protected:
    static GameMap *m_instance;           /* 单例实例对象空间指针 */
    int *mp;                              /* 映射数组 */
    int food_count;                       /* 食物数量 */
    int max_food_count;                   /* 最大食物数量 */
    BMP bg;                               /* 背景图片 */
    BMP fast_bg;                          // 加速背景
    BMP slow_bg;                          // 减速背景
    BMP food_score1;                      // 加1分果实
    BMP food_score2;                      // 加2分果实
    BMP food_speedup;                     // 加速果实
    BMP food_speeddown;                   // 减速果实
    BMP food_confuse;                     // 迷惑果实（方向反转）
    BMP food_bomb;                        // 炸弹果实（缩短蛇身/游戏结束）
    BMP food_ai_snake;                    // AI蛇身果实
    GridState grid[GRID_ROWS][GRID_COLS]; /* 网格数组 */
};

// 简单难度
class EasyGameMap : public GameMap
{
protected:
    EasyGameMap(int *mp) : GameMap(mp, "./res/slow_bg.bmp") { setMaxFoodCount(); }
    friend class GameMap;

    // 实现概率
    int getScore1Prob() const override { return 50; }
    int getScore2Prob() const override { return 30; }
    int getSpeedUpProb() const override { return 10; }
    int getSpeedDownProb() const override { return 5; }
    int getConfuseProb() const override { return 3; }
    int getAISnake() const override { return 0; }
    int getBombProb() const override { return 2; }
    bool isCreatedAISnake() const override { return false; }
    int getInitSpeed() const override { return 7; }
    int getMaxSpeed() const override { return 5; }
    int getMinSpeed() const override { return 10; }
    void setMaxFoodCount() override { max_food_count = 20; }
};

// 中等难度
class MediumGameMap : public GameMap
{
protected:
    MediumGameMap(int *mp) : GameMap(mp, "./res/bg.bmp") { setMaxFoodCount(); }
    friend class GameMap;

    int getScore1Prob() const override { return 39; }
    int getScore2Prob() const override { return 25; }
    int getSpeedUpProb() const override { return 10; }
    int getSpeedDownProb() const override { return 10; }
    int getConfuseProb() const override { return 10; }
    int getBombProb() const override { return 5; }
    int getAISnake() const override { return 1; }
    bool isCreatedAISnake() const override { return false; }
    int getInitSpeed() const override { return 5; }
    int getMaxSpeed() const override { return 3; }
    int getMinSpeed() const override { return 7; }
    void setMaxFoodCount() override { max_food_count = 15; }
};

// 困难难度
class HardGameMap : public GameMap
{
protected:
    HardGameMap(int *mp) : GameMap(mp, "./res/fast_bg.bmp") { setMaxFoodCount(); }
    friend class GameMap;

    int getScore1Prob() const override { return 30; }
    int getScore2Prob() const override { return 20; }
    int getSpeedUpProb() const override { return 15; }
    int getSpeedDownProb() const override { return 5; }
    int getConfuseProb() const override { return 10; }
    int getBombProb() const override { return 10; }
    int getAISnake() const override { return 10; }
    bool isCreatedAISnake() const override { return true; }
    int getInitSpeed() const override { return 4; }
    int getMaxSpeed() const override { return 2; }
    int getMinSpeed() const override { return 5; }
    void setMaxFoodCount() override { max_food_count = 10; }
};

#endif
